package com.framework.auth.ext;

import com.framework.auth.service.IUserService;
import com.framework.auth.translator.AuthenticationResultHandler;
import com.framework.common.exception.BusinessException;
import com.framework.common.util.SpringUtils;
import com.framework.common.util.StringUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;

/**
 * 这里直接插入一个filter事先过滤
 * 用于设置默认用户密码，不登录
 * 也可以写成自定义： converter -> token -> provider的处理模式
 */
public class AuthenticationServerUserFilter extends OncePerRequestFilter {
    private AuthenticationResultHandler authenticationFailureHandler = new AuthenticationResultHandler();

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String responseType = request.getParameter(OAuth2ParameterNames.RESPONSE_TYPE);
        String userName = request.getParameter("username");

        try {
            if (StringUtils.isNotBlank(responseType)) {
                // 只有code模式，给默认密码，不需要登录
                if (OAuth2AuthorizationResponseType.CODE.getValue().equals(responseType) && StringUtils.isNotBlank(userName)) {
                    setEmptyAuthenticationServerUser(userName);
                } else {
                    if (!OAuth2AuthorizationResponseType.TOKEN.getValue().equals(responseType)) {
                        throw new BusinessException("response_type 的值只能为：code、token");
                    }
                }
            }
            filterChain.doFilter(request,response);
        } catch (Exception e) {
            authenticationFailureHandler.onParameterFailure(request, response, e);
        }
    }

    private void setEmptyAuthenticationServerUser(String userName) {
        IUserService userService = SpringUtils.getBean(IUserService.class);
        boolean exists = userService.exists(userName);
        if (!exists) {
            throw new BusinessException("用户不存在");
        }
        User user = new User(userName, StringUtils.EMPTY, new ArrayList<>());
        PreAuthenticatedAuthenticationToken authenticationServerUserToken = new PreAuthenticatedAuthenticationToken(user, userName, new HashSet<>());
        authenticationServerUserToken.setAuthenticated(true);
        SecurityContextHolder.getContext().setAuthentication(authenticationServerUserToken);
    }
}
